package com.yuanfeng.payment.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yuanfeng.commoms.config.YFConfig;
import com.yuanfeng.commoms.constant.CommonStatusEnum;
import com.yuanfeng.commoms.exception.BizCodeEnume;
import com.yuanfeng.commoms.util.*;
import com.yuanfeng.commoms.vo.user.UserInfoVO;
import com.yuanfeng.payment.common.PayCommonUtils;
import com.yuanfeng.payment.entity.PayUserBaseEntity;
import com.yuanfeng.payment.entity.PayUserResourceEntity;
import com.yuanfeng.payment.feign.UsermsServiceClient;
import com.yuanfeng.payment.mapper.PayAssetDetailsMapper;
import com.yuanfeng.payment.mapper.PayUserBaseMapper;
import com.yuanfeng.payment.mapper.PayUserResourceMapper;
import com.yuanfeng.payment.service.PayUserBaseService;
import com.yuanfeng.payment.service.PayUserResourceService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 *
 */
@Service
public class PayUserBaseServiceImpl extends ServiceImpl<PayUserBaseMapper, PayUserBaseEntity>
    implements PayUserBaseService{

    @Autowired
    private PayUserResourceService payUserResourceService;
    @Autowired
    private PayUserResourceMapper payUserResourceMapper;
    @Autowired
    private PayAssetDetailsMapper payAssetDetailsMapper;
    @Autowired
    private UsermsServiceClient usermsServiceClient;
    @Autowired
    private PayCommonUtils payCommonUtils;


    static Integer errorNum = 0;// 错误次数
    static Integer errorSum = 3;// 总次数

    @Override
    public ResponseResult createUser(String userId) {
        PayUserBaseEntity record = new PayUserBaseEntity();
        record.setUserId(userId);

        int isInsertByUserBaseSuccess = this.baseMapper.insert(record);
        PayUserResourceEntity payUserResourceEntity = new PayUserResourceEntity();
        payUserResourceEntity.setUserId(userId);
        boolean isInsertByUseResourceSuccess = payUserResourceService.save(payUserResourceEntity);

        return isInsertByUseResourceSuccess ? ResponseResult.success() : ResponseResult.fail();
    }

    @Override
    public ResponseResult setPaymentPassword(Map<String, Object> map) {
        String token = (String) map.get("token");
        // 获取验证码
        String verifyCode = (String) map.get("verifyCode");
        // verify:1 设置支付密码 2：找回支付密码
        try {
            // 获取user信息
            UserInfoVO ui = ParseTokenUtils.getUserInfoByToken(token);
            String userId = ui.getUserId();


            //将密码加密
            String password = PasswordUtils.BCryptPasswordEncoder((String) map.get("passwd"));
            String code = RedisUtil.get(YFConfig.YF_VERIFICODE_CLIENT_SESSION_ID + "_" + token);
            if (verifyCode.equals(code)) {
                boolean isChangePasswd = this.baseMapper.update(null, new LambdaUpdateWrapper<PayUserBaseEntity>()
                        .eq(PayUserBaseEntity::getUserId, userId)
                        .set(PayUserBaseEntity::getUserPayPasswd, password)) == CommonStatusEnum.SUCCESS.getCode();
                if (isChangePasswd) {
                    return ResponseResult.success(BizCodeEnume.PASSWORD_UPDATED_SUCCESSFULLY);
                } else {
                    return ResponseResult.fail();
                }
            } else {
                return ResponseResult.fail(BizCodeEnume.INCORRECT_VERIFICATION_CODE);
            }
        } catch (Exception e) {
            return ResponseResult.fail(e.getMessage());
        }
    }

    @Override
    public ResponseResult checkPayPassword(Map<String, String> paraMap) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(paraMap.get("token"));
        if (null == userInfo){
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID.getCode(),BizCodeEnume.TOKEN_IS_INVALID.getMsg());
        }
        paraMap.put("userId",userInfo.getUserId());
        Integer flag = this.baseMapper.checkPayPassword(paraMap);
        return ResponseResult.success(flag);
    }

    @Override
    public ResponseResult updatePaymentPassword(Map<String, Object> map) {
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(map.get("token").toString());
        if (null == userInfo){
            return ResponseResult.fail(BizCodeEnume.TOKEN_IS_INVALID);
        }
        String passwd = PasswordUtils.BCryptPasswordEncoder((String) map.get("passwd"));
        Integer isChangePasswd = this.baseMapper.update(null, new LambdaUpdateWrapper<PayUserBaseEntity>()
                .set(PayUserBaseEntity::getUserPayPasswd, passwd)
                .eq(PayUserBaseEntity::getUserId, userInfo.getUserId()));
        if (isChangePasswd > 0) {
            return ResponseResult.success();
        }
        return ResponseResult.fail(BizCodeEnume.UPDATE_ERROR);
    }

    @Override
    public ResponseResult plusMemberpay(Map<String, Object> map) {
        Map<Object,Object> assetDetailMap = new HashMap<>();
        String token = (String) map.get("token");
        UserInfoVO userInfo = ParseTokenUtils.getUserInfoByToken(token);
        String userId = userInfo.getUserId();
        String passwd = String.valueOf(map.get("passwd"));

        //创建支付单号
        int i = PayToolUtil.buildRandom(6);
        SimpleDateFormat format = new SimpleDateFormat("yyyyMMdd");
        StringBuffer plusorder = new StringBuffer("PLUS");
        plusorder.append(format.format(new Date()));
        plusorder.append(i);
        // 1:余额支付 2:购物卡支付
        Integer type = Integer.parseInt(map.get("type") + "");

        try {
            // 1:余额支付 2:购物卡支付
            if (type == 1) {
                //输错次数
                String errorCount = RedisUtil.get(YFConfig.YF_USERID_SHOPID + userInfo.getUserId());
                if( null != errorCount && errorSum.equals(Integer.valueOf(errorCount))){
                    return ResponseResult.fail(BizCodeEnume.PAY_PASSWORD_ERROR.getCode(),BizCodeEnume.PAY_PASSWORD_ERROR.getMsg());
                }
                // 验证支付密码
                // 验证支付密码
                Integer isExist = payCommonUtils.getPwdExist(passwd, userInfo).getCode();
                if (isExist == 1) {
                    //支付金额
                    String payPrice = String.valueOf(map.get("payPrice"));
                    BigDecimal amountActuallyPaids = new BigDecimal(payPrice);
                    // 查询账户余额
                    BigDecimal userBalanceMoney = payUserResourceMapper.queryBalanceMoney(userId);
                    // 判断实付金额与余额
                    if (userBalanceMoney.compareTo(amountActuallyPaids) == 1
                            || userBalanceMoney.compareTo(amountActuallyPaids) == 0) {
                        // 扣除购物金额
                        boolean updateMoney = payUserResourceMapper.updateMoney(userId, amountActuallyPaids);
                        if (updateMoney) {
                            assetDetailMap.put("assetDirection", "开通plus会员");
                            assetDetailMap.put("payType",1);
                            assetDetailMap.put("userId",userId);
                            assetDetailMap.put("detailType",9);
                            assetDetailMap.put("assetType",2);
                            assetDetailMap.put("assetAmount",amountActuallyPaids);
                            assetDetailMap.put("orderId",plusorder.toString());
                            payAssetDetailsMapper.insertDetail(assetDetailMap);

                            //插入plus会员信息
                            map.put("plusOrder",plusorder.toString());
                            usermsServiceClient.plusmemberopen(map);
                            return ResponseResult.success();

                        } else {
                            return ResponseResult.fail(0, "支付失败！");
                        }
                    } else {
                        return ResponseResult.fail(0, "账户余额不足，请选择其他支付方式!");
                    }
                } else {
                    Integer numCount = null;//次数统计
                    if( null == errorCount ){
                        numCount = 1;
                        RedisUtil.set(YFConfig.YF_USERID_SHOPID + userInfo.getUserId(),numCount.toString(),60*60);
                    }else{
                        String s1 = RedisUtil.get(YFConfig.YF_USERID_SHOPID + userInfo.getUserId().toString());
                        numCount = Integer.valueOf(s1) + 1;
                        RedisUtil.set(YFConfig.YF_USERID_SHOPID + userInfo.getUserId(),numCount.toString(),60*60);
                    }

                    return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),"支付密码不正确，您还有"+(errorSum - numCount)+"次输入机会！");
                }

            } else if (type == 2) {
                // 购物卡支付
                //输错次数
                String errorCount = RedisUtil.get(YFConfig.YF_USERID_SHOPID + userInfo.getUserId());
                if( null != errorCount && errorSum.equals(Integer.valueOf(errorCount))){
                    return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),"支付密码不正确，您已经尝试3次，支付密码将锁定1小时，或找回密码后重试！");
                }
                Integer isExist = payCommonUtils.getPwdExist(passwd, userInfo).getCode();
                if (isExist == 1) {

                    //支付金额
                    String payPrice = String.valueOf(map.get("payPrice"));
                    BigDecimal amountActuallyPaids = new BigDecimal(payPrice);
                    // 查询账户购物卡余额
                    BigDecimal userGiftCardMoney = payUserResourceMapper.queryGiftCardMoney(userId);

                    // 判断实付金额与余额
                    if (userGiftCardMoney.compareTo(amountActuallyPaids) == 1
                            || userGiftCardMoney.compareTo(amountActuallyPaids) == 0) {
                        // 扣除购物金额
                        boolean updateMoney = payUserResourceMapper.updateGiftCardMoney(userId, amountActuallyPaids);
                        if (updateMoney) {
                            assetDetailMap.put("assetDirection", "开通plus会员");
                            assetDetailMap.put("payType",2);
                            assetDetailMap.put("userId",userId);
                            assetDetailMap.put("detailType",9);
                            assetDetailMap.put("assetType",2);
                            assetDetailMap.put("assetAmount",amountActuallyPaids);
                            assetDetailMap.put("orderId",plusorder.toString());
                            payAssetDetailsMapper.insertDetail(assetDetailMap);

                            //插入plus会员信息
                            map.put("plusOrder",plusorder.toString());
                            usermsServiceClient.plusmemberopen(map);
                            return ResponseResult.success(BizCodeEnume.OPERATION_SUCCESSFUL);
                        } else {
                            return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),"支付失败！");
                        }
                    } else {
                        return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),"账户余额不足，请选择其他支付方式!");
                    }
                } else {
                    //次数统计
                    Integer numCount = null;
                    if( null == errorCount ){
                        numCount = 1;
                        RedisUtil.set(YFConfig.YF_USERID_SHOPID + userInfo.getUserId(),numCount.toString(),60*60);
                    }else{
                        String s1 = RedisUtil.get(YFConfig.YF_USERID_SHOPID + userInfo.getUserId());
                        numCount = Integer.valueOf(s1) + 1;
                        RedisUtil.set(YFConfig.YF_USERID_SHOPID + userInfo.getUserId(),numCount.toString(),60*60);
                    }
                    return ResponseResult.fail(CommonStatusEnum.FAIL.getCode(),"支付密码不正确，您还有"+(errorSum - numCount)+"次输入机会！");
                }
            }
        } catch (Exception e) {
            return ResponseResult.fail(e.getMessage());
        }
        return ResponseResult.fail(BizCodeEnume.SYSTEM_ERROR.getCode(),BizCodeEnume.SYSTEM_ERROR.getMsg());
    }
}




